package org.xtext.runtime.plan;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.xtext.runtime.formula.Goal;
import org.xtext.runtime.formula.MentalEvent;
import org.xtext.runtime.interpreter.Agent;
import org.xtext.runtime.term.Variable;
import org.xtext.runtime.util.Bindings;


public class GoalStep implements IPlanStep {
	private Goal goal;
//	private Bindings unbound;
	
	int state = 0;
	
	public GoalStep(Goal goal) {
		this.goal = goal;
	}
	
	public void handle(Agent agent, PlanStack planStack) {
		switch(state) {
		case 0:
			if (!agent.addEvent(new MentalEvent(MentalEvent.ADDITION, goal, planStack))) {
				agent.logAction("+" + goal + " [FAILED: There is not corresponding plan rule]");
				System.out.println("+" + goal + " [FAILED: There is not corresponding plan rule]");
				planStack.fail();
				return;
			}

			// push the step back onto the stack so it can be rechecked when the
			// subplan is completed...
			planStack.back();

			state = 1;
			agent.logAction("+" + goal + " [INVOKING]");
			planStack.suspend();
			break;
		case 1:
			state = 0;
			agent.logAction("+" + goal + " [SUCCESS]");
		}
	}
	
	public String toString() {
		return toString("");
	}
	
	public String toString(String tabs) {
		return tabs + goal;
	}
	
	public String toFullString(String tabs) {
		return toString(tabs);
	}
	
	public IPlanStep apply(Bindings set) {
		return this;
	}

	@Override
	public Set<Variable> variables() {
		Set<Variable> variables = new HashSet<Variable>();
		variables.addAll(this.goal.variables());
		return variables;
	}

	@Override
	public IPlanStep copy(Map<String, Variable> vars) {
		return new GoalStep(goal.copy(vars));
	}

	@Override
	public void reset() {
	}
}
